package wiki.hitime.stl.daq.util;

import com.alibaba.fastjson.JSON;
import wiki.hitime.stl.daq.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.quartz.CronExpression;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

/**
 * @author zhangdaoping
 * @create 2019-07-09 11:05
 */
@Slf4j
public class CronUtils {

    /**
     * 解析有效时间集合
     *
     * @param cronExpressionStr cron表达式
     * @param parserStartDate   解析开始日期
     * @param validTimeCount    需要的有效日期数量
     * @param validTimeList     有效日期集合
     * @return
     */
    public static boolean parserValidTimeList(String cronExpressionStr, Date parserStartDate, int validTimeCount, List<String> validTimeList) {
        if (StringUtils.isEmpty(cronExpressionStr) || parserStartDate == null || validTimeCount == 0) {
            log.error("解析参数有误");
            return false;
        }
        try {
            CronExpression cronExpression = new CronExpression(cronExpressionStr);
            if (validTimeList == null) {
                validTimeList = new ArrayList<>(validTimeCount);
            }
            Date validDate = parserStartDate;
            for (int i = 0; i < validTimeCount; i++) {
                validDate = cronExpression.getNextValidTimeAfter(validDate);
                validTimeList.add(new DateTime(validDate).toString("yyyy-MM-dd HH:mm:ss"));
            }
            return true;
        } catch (ParseException e) {
            log.error("表达式解析错误");
            return false;
        }
    }

    /**
     * 获取下一次执行的毫秒数
     *
     * @param cronExpressionStr cron表达式
     * @param parserStartDate   解析开始日期
     * @return
     * @throws ParseException
     */
    public static Long parserNextFiredTime(String cronExpressionStr, Date parserStartDate) throws ServiceException {
        try {
            CronExpression cronExpression = new CronExpression(cronExpressionStr);
            Date nextFiredDate = cronExpression.getNextValidTimeAfter(parserStartDate);
            System.out.println(cronExpression.getExpressionSummary());
            System.out.println(cronExpression.toString());
            return nextFiredDate.getTime();
        } catch (ParseException e) {
            log.error("表达式解析错误，cronExpressionStr={}，parserStartDate={}", cronExpressionStr, JSON.toJSONString(parserStartDate));
            throw new ServiceException("表达式解析错误");
        }
    }

    public static String parserDescription(String cronExpressionStr, Date parserStartDate) {
        return null;
    }


    /**
     * 测试
     *
     * @param args
     */
    public static void main(String[] args) throws ServiceException {
        String cronExpressionStr = "0 1/1 * * * ?";
        DateTime parserStartDate = DateTime.now();
        List<String> resultList = new ArrayList<>();
        boolean result = parserValidTimeList(cronExpressionStr, parserStartDate.toDate(), 4, resultList);
        if (result) {
            for (String timeStr : resultList) {
                System.out.println(timeStr);
            }
        }
        System.out.println(parserNextFiredTime(cronExpressionStr, parserStartDate.toDate()));
        StringTokenizer stringTokenizer=new StringTokenizer(cronExpressionStr," \t",false);
        while (stringTokenizer.hasMoreElements()){
            System.out.println(stringTokenizer.nextElement());
        }
    }
}
